﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Engine.Sgml.Matching;
using System.Diagnostics;

namespace Engine.Sgml.Merging {
    internal sealed class SequenceCaptureAllocator : ICaptureAllocator {

        public void Insert(Match match, ref Capture capture, ref int index) {
            if (index < 0) {
                index = match.Captures.Count;
                while (--index >= 0) {
                    Capture c = match.Captures[index];
                    if (c.Success || c.Entity.IsIllegalElement)
                        break;
                    }
                if (index < 0) {
                    index = match.StartIndex;
                    capture.Entity.Move(match, match.Ancestor, index);
                    }
                else
                    capture.Entity.Move(match, match.Ancestor, match.Captures[index].EndIndex + 1);
                }
            else {
                if (index >= match.Captures.Count)
                    throw new ArgumentOutOfRangeException("index");
                while (index + 1 < match.Captures.Count) {
                    Capture c = match.Captures[index + 1];
                    if (c.Entity.IsInclusion || c.Entity.IsIllegalElement)
                        index++;
                    else
                        break;
                    }
                Debug.Assert(match.Captures[index].Entity.IsIllegalElement ? true : match.Captures[index].Success);
                capture.Entity.Move(match, match.Ancestor, match.Captures[index].EndIndex + 1);
                }
            match.Captures.Insert(++index, capture);
            Debug.Assert(MatchTestUtility.Verify(match));
            }

        public void Replace(Match match, ref Capture capture, int index) {
            if (index < 0 || index >= match.Captures.Count)
                throw new ArgumentOutOfRangeException("index");
            int position = index;
            while (--position >= 0) {
                Capture c = match.Captures[position];
                if (c.Success || c.Entity.IsIllegalElement) {
                    position = c.EndIndex + 1;
                    break;
                    }
                }
            if (position < 0)
                position = match.StartIndex;
            capture.Entity.Move(match, match.Ancestor, position);
            match.Captures[index] = capture;
            Debug.Assert(MatchTestUtility.Verify(match));
            }

        public bool Add(Match match, ref Capture capture) {
            return false;
            }
        }
    }
